﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls.Base;
using Silvermoon.Visuals;
using System.Drawing;
using Silvermoon.Utils;
using Silvermoon.Controls.Interfaces;
using Silvermoon.OpenGL;

namespace Silvermoon.Controls
{
    /// <summary>
    /// A button that uses images to present it's state.
    /// </summary>
    public class ImageButton : ButtonBase, IContextMenuBehavior
    {
        private ImageVisual image;
        private ImageVisual iconImage;
        private Texture icon;
        private Texture normalStateImage;
        private Texture pressedStateImage;
        private Texture disabledStateImage;
        private Color color;
        private Color iconColor = Color.White;
        private Color pressedColor;

        public ImageButton()
            : base()
        {
            image = new ImageVisual();
        }

        public override void Dispose()
        {
            image.Dispose();
            image = null;
            Visuals = null;
            base.Dispose();
        }

        /// <summary>
        /// Gets or sets the icon onto the button.
        /// </summary>
        public Texture Icon
        {
            get { return icon; }
            set
            {
                if (icon != value)
                {
                    icon = value;
                    Invalidate(InvalidationFlag.LayoutAppearance);
                }
            }
        }

        /// <summary>
        /// Gets or sets the color that is used for the specified Icon.
        /// </summary>
        public Color IconColor { get { return iconColor; } set { if (iconColor != value) { iconColor = value; Invalidate(InvalidationFlag.TextColor); } } }

        /// <summary>
        /// Gets or sets the texture image that holds the normal state image of the button.
        /// </summary>
        public Texture Image
        {
            get { return normalStateImage; }
            set { if (normalStateImage != value) { normalStateImage = value; Invalidate(InvalidationFlag.Appearance); } }
        }

        /// <summary>
        /// Gets or sets the texture image that holds the disabled state image of the button.
        /// </summary>
        public Texture DisabledImage
        {
            get { return disabledStateImage ?? normalStateImage; }
            set { if (disabledStateImage != value) { disabledStateImage = value; Invalidate(InvalidationFlag.Appearance); } }
        }


        /// <summary>
        /// Gets or sets the texture image that holds the pressed state image of the button.
        /// If no image is specified, the control uses the NormalImage image to render when in pressed stated.
        /// </summary>
        public Texture PressedImage
        {
            get { return pressedStateImage ?? normalStateImage; }
            set { if (pressedStateImage != value) { pressedStateImage = value; Invalidate(InvalidationFlag.Appearance); } }
        }

        public Color Color { get { return color; } set { if (color != value) { color = value; Invalidate(InvalidationFlag.Color); } } }

        public Color PressedColor { get { return pressedColor.IsEmpty ? color : pressedColor; } set { if (pressedColor != value) { pressedColor = value; Invalidate(InvalidationFlag.Color); } } }

        protected override void OnLayout()
        {
            if (CheckFlag(InvalidationFlag.LayoutAppearance | InvalidationFlag.Size | InvalidationFlag.Margin))
            {
                if (icon != null)
                {

                    if (iconImage == null)
                    {
                        iconImage = new ImageVisual { Image = icon};
                    }
                    Size size = icon.Size;
                    int offset = IsDownOrPressed ? 2 : 0;
                    iconImage.Bounds = Control.ScaledRect((Width - size.Width) / 2, (Height - size.Height) / 2 + offset, size.Width, size.Height);
                }
            }
            if (CheckFlag(InvalidationFlag.TextColor) && iconImage != null)
            {
                iconImage.Color = iconColor;
            }

            Texture e = Enabled ? (this.IsDownOrPressed ? PressedImage : Image) : DisabledImage;
            if (e != null)
            {
                image.Color = IsDownOrPressed ? PressedColor : Color;
                image.Bounds = Control.Scale(ClientBounds);
                image.Image = e;
                image.Visible = true;
                if (!Enabled)
                {
                    if (disabledStateImage == null)
                    {
                        image.Color = ColorUtil.AlphaBlendColor(color, Color.Black, 128);
                    }
                }
            }
            else image.Visible = false;
            base.OnLayout();
        }

        public override IEnumerable<Visual> Visuals
        {
            get
            {
                if (image != null && image.Visible) yield return image;
                if (iconImage != null) yield return iconImage;
            }
        }


        #region IContextMenuBehavior Members

        public ContextMenu ContextMenu { get; set; }

        #endregion
    }
}
